package main

import (
	"context"
	"fmt"
	"html/template"
	"log"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"gin-gateway/core/init"
	"github.com/gorilla/websocket"
)

// var addr = flag.String("addr", "localhost:2001", "http service address")
var addr string
var serviceName = "test_websocket"
var host string

var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
} // use default options

func echo(w http.ResponseWriter, r *http.Request) {
	c, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Print("upgrade:", err)
		return
	}
	defer c.Close()
	for {
		mt, message, err := c.ReadMessage()
		if err != nil {
			log.Println("read:", err)
			break
		}
		log.Printf("recv: %s", message)
		err = c.WriteMessage(mt, message)
		if err != nil {
			log.Println("write:", err)
			break
		}
	}
}

func home(w http.ResponseWriter, r *http.Request) {
	homeTemplate.Execute(w, fmt.Sprintf("ws://%s/echo", host))
}

func main() {
	// flag.Parse()

	host = os.Getenv("WS_ENTRY")
	if host == "" {
		log.Fatal("WS_ENTRY should be set")
	}

	// 环境变量中格式为 "websocketbackend,2003,50"
	sc := strings.Split(os.Getenv("BACKEND_SCHEME"), ",")
	if len(sc) != 3 {
		log.Fatal("BACKEND_SCHEME should be set")
	}
	addr = fmt.Sprintf("0.0.0.0:%s", sc[1])

	mux := http.NewServeMux()
	mux.HandleFunc("/echo", echo)
	mux.HandleFunc("/", home)
	server := &http.Server{
		Addr:         addr,
		WriteTimeout: time.Second * 3,
		Handler:      mux,
	}
	go func() {
		log.Println("Starting websocket at " + addr)
		server.ListenAndServe()
	}()

	etcdServer := os.Getenv("ETCD_SERVER")
	if len(etcdServer) == 0 {
		log.Fatal("ETCD_SERVER should be set")
	}
	registry, err := Init.NewEtcdRegistry([]string{etcdServer}, time.Duration(5))
	if err != nil {
		panic(err)
	}

	// 格式："test_strip_uri/2001"
	endpoint := fmt.Sprintf("%s/%s", serviceName, sc[1])
	// 注册格式： "websocketbackend:2001,50"
	err = registry.Register(endpoint, fmt.Sprintf("%s:%s,%s", sc[0], sc[1], sc[2]))
	if err != nil {
		panic(err)
	}

	//监听关闭信号
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit

	server.Close()
	err = registry.Unregister(context.Background(), endpoint)
	if err != nil {
		fmt.Println("unregister")
		panic(err)
	}
	fmt.Printf("close server: %s", addr)

	err = registry.Close()
	if err != nil {
		panic(err)
	}
}

var homeTemplate = template.Must(template.New("").Parse(`
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script>  
window.addEventListener("load", function(evt) {

    var output = document.getElementById("output");
    var input = document.getElementById("input");
    var ws;

    var print = function(message) {
        var d = document.createElement("div");
        d.innerHTML = message;
        output.appendChild(d);
    };

    document.getElementById("open").onclick = function(evt) {
        if (ws) {
            return false;
        }
		var web_url=document.getElementById("web_url").value
        ws = new WebSocket(web_url);
        ws.onopen = function(evt) {
            print("OPEN");
        }
        ws.onclose = function(evt) {
            print("CLOSE");
            ws = null;
        }
        ws.onmessage = function(evt) {
            print("RESPONSE: " + evt.data);
        }
        ws.onerror = function(evt) {
            print("ERROR: " + evt.data);
        }
        return false;
    };

    document.getElementById("send").onclick = function(evt) {
        if (!ws) {
            return false;
        }
        print("SEND: " + input.value);
        ws.send(input.value);
        return false;
    };

    document.getElementById("close").onclick = function(evt) {
        if (!ws) {
            return false;
        }
        ws.close();
        return false;
    };

});
</script>
</head>
<body>
<table>
<tr><td valign="top" width="50%">
<p>Click "Open" to create a connection to the server, 
"Send" to send a message to the server and "Close" to close the connection. 
You can change the message and send multiple times.
<p>
<form>
<button id="open">Open</button>
<button id="close">Close</button>
<p><input id="web_url" type="text" value="{{.}}">
<p><input id="input" type="text" value="Hello world!">
<button id="send">Send</button>
</form>
</td><td valign="top" width="50%">
<div id="output"></div>
</td></tr></table>
</body>
</html>
`))
